﻿///<copyright>
/// Copyright © 2009 Stephen Styrchak. All Rights Reserved.
///</copyright>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Ferpect.ComponentModel.Sprites
{
    public class SpriteBatchStack : Component
    {
        private Stack<SpriteBatchInfo> spriteBatches;
        private IGraphicsDeviceService graphicsService;

        public SpriteBatchStack()
        {
            this.spriteBatches = new Stack<SpriteBatchInfo>();
        }

        public IGraphicsDeviceService GraphicsService
        {
            get
            {
                this.EnsureGraphicsDeviceService();
                return this.graphicsService;
            }
        }

        private void EnsureGraphicsDeviceService()
        {
            if (this.graphicsService == null)
            {
                this.graphicsService = (IGraphicsDeviceService)this.GetService(typeof(IGraphicsDeviceService));
                if (this.graphicsService == null)
                {
                    throw new InvalidOperationException("IGraphicsDeviceService could not be reached. This component must be sited in a container that provides IGraphicsDeviceService.");
                }
            }
        }

        public void Push(SpriteBatchInfo batchInfo)
        {
            if (batchInfo == null)
            {
                throw new ArgumentNullException("batchInfo");
            }
            if (this.spriteBatches.Count > 0)
            {
                this.spriteBatches.Peek().End();
            }
            this.spriteBatches.Push(batchInfo);
        }

        public SpriteBatchInfo Pop()
        {
            if (this.spriteBatches == null)
            {
                throw new ObjectDisposedException("SpriteBatchStack");
            }
            SpriteBatchInfo batchInfo = this.spriteBatches.Pop();
            batchInfo.End();
            return batchInfo;
        }

        public int Count
        {
            get
            {
                if (this.spriteBatches == null)
                {
                    return 0;
                }
                return this.spriteBatches.Count;
            }
        }

        /// <summary>
        /// Current always returns a SpriteBatch
        /// </summary>
        public SpriteBatch Current
        {
            get
            {
                if (this.spriteBatches != null && this.spriteBatches.Count > 0)
                {
                    return this.spriteBatches.Peek().Begin();
                }
                return null;
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.spriteBatches != null)
                {
                    while (this.spriteBatches.Count > 0)
                    {
                        this.Pop();
                    }
                    this.spriteBatches = null;
                }
            }
            base.Dispose(disposing);
        }
    }
}
